package com.zgjkhis.modules.system.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.github.pagehelper.PageInfo;
import com.zgjkhis.common.service.impl.BaseServiceImpl;
import com.zgjkhis.domain.PageResult;
import com.zgjkhis.dozer.service.IGenerator;
import com.zgjkhis.exception.ServiceException;
import com.zgjkhis.modules.basicsetting.service.dto.AdditionalQueryCriteria;
import com.zgjkhis.modules.basicsetting.service.dto.DrugInfoQueryCriteria;
import com.zgjkhis.modules.enums.DrugTypeEnum;
import com.zgjkhis.modules.security.security.LoginUserUtil;
import com.zgjkhis.modules.system.domain.Drug;
import com.zgjkhis.modules.system.domain.vo.DrugBatchVO;
import com.zgjkhis.modules.system.service.DrugService;
import com.zgjkhis.modules.system.service.dto.DrugDto;
import com.zgjkhis.modules.system.service.dto.DrugQueryCriteria;
import com.zgjkhis.modules.system.service.dto.DrugStockWarningDto;
import com.zgjkhis.modules.system.service.dto.DrugTypeCountDto;
import com.zgjkhis.modules.system.service.mapper.DrugMapper;
import com.zgjkhis.modules.util.CharUtil;
import com.zgjkhis.modules.util.PingYinUtil;
import com.zgjkhis.utils.FileUtil;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;

/**
 * @Author yzq
 * @Description 药品
 * @Date 2021/6/23 9:47
 * @Param
 * @return
 **/
@Service
//@CacheConfig(cacheNames = "user")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DrugServiceImpl extends BaseServiceImpl<DrugMapper, Drug> implements DrugService {

    private final IGenerator generator;

    public DrugServiceImpl(IGenerator generator) {
        this.generator = generator;
    }

    @Override
    public PageResult<Drug> findAllByPageable(DrugQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<Drug> page = new PageInfo<>(baseMapper.findAllByPageable(criteria));
        return PageResult.data(page);
    }

    @Override
    public List<Drug> findAllByPageable(DrugQueryCriteria criteria) {
        return baseMapper.findAllByPageable(criteria);
    }

    @Override
    public DrugDto findDetailById(String id) {
        Drug drug = this.getById(Long.valueOf(id));
        return generator.convert(drug, DrugDto.class);
    }

    @Override
    public List<DrugTypeCountDto> findCountByDrugType(DrugQueryCriteria criteria) {
        return baseMapper.findCountByDrugType(criteria);
    }

    @Override
    @Transactional
    public boolean batchUpdateWarning(List<DrugBatchVO> list) {
        List<Drug> drugslist = new ArrayList<>();
        for (DrugBatchVO drugBatchVO : list) {
            Drug drug = new Drug();
            drug.setId(drugBatchVO.getId());
            drug.setStockWarning(drugBatchVO.getWarnNum());
            drugslist.add(drug);
        }
        return this.updateBatchById(drugslist);
    }

    @Override
    public boolean batchUpdateStatus(List<DrugBatchVO> list) {
        List<Drug> drugslist = new ArrayList<>();
        for (DrugBatchVO drugBatchVO : list) {
            Drug drug = new Drug();
            drug.setId(drugBatchVO.getId());
            drug.setStatus(drugBatchVO.getStatus());
            drugslist.add(drug);
        }
        return this.updateBatchById(drugslist);
    }

    @Override
    public void dowonload(List<Drug> drugs, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Drug drug : drugs) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("药品ID", drug.getId());
            map.put("药品名称", drug.getDrugName());
            map.put("药品分类", DrugTypeEnum.findByCode(drug.getDrugType()));
            map.put("规格", drug.getDrugSpec());
            map.put("单位", drug.getDoseUnit());
            map.put("生产厂家", drug.getDrugManufactor());
            map.put("售价", drug.getSalePrice());
            map.put("库存", drug.getStock());
            map.put("有效标志", drug.getStatus() == 0 ? "正常" : "失效");
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional
    public void batchUpdateSalsePrice(MultipartFile file) throws IOException {
        ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
        List<List<Object>> listAll = excelReader.read();
        for (int i = 1; i < listAll.size(); i++) {
            List<Object> rowlist = listAll.get(i);
            Long id = (Long) rowlist.get(0);
            Double salsePrice = (Double) rowlist.get(6);
            Drug drug = new Drug();
            drug.setId(id);
            drug.setSalePrice(BigDecimal.valueOf(salsePrice));
            this.updateById(drug);
        }
    }

    @Override
    public void batchSave(MultipartFile file, String flag) throws IOException {
        ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
        List<List<Object>> listAll = excelReader.read();
        List<Drug> list = new ArrayList<>();
        for (int i = 1; i < listAll.size(); i++) {


//            上传类型：1：西药，中成药，2：中药饮片和配方颗粒，3：耗材
            Drug temp = new Drug();
            List<Object> rowlist = listAll.get(i);
            if ("1".equals(flag)) {
                temp = saveByFlag1(rowlist);
                list.add(temp);
            } else if ("2".equals(flag)) {
                temp = saveByFlag2(rowlist);
                list.add(temp);
            } else if ("3".equals(flag)) {
                temp = saveByFlag3(rowlist);
                list.add(temp);
            }
        }
        this.saveBatch(list);
    }

    @Override
    public List<DrugStockWarningDto> findStockWarning(String pharmacyId) {
        return this.baseMapper.findStockWarning(pharmacyId);
    }

    @Override
    public void updateStockById(Long id) {
        baseMapper.updateStockById(id);
    }

    @Override
    public void updateStockByIdForDelivery(Long id) {
        baseMapper.updateStockByIdForDelivery(id);
    }

    @Override
    public void updateMothUseById(Long id, Integer deliveryNum, Integer minDeliveryNum) {
        Drug drug = this.getById(id);
        int moth = drug.getMothUse();
        int minMoth = drug.getMinMothUse();
        int totalDose = 1;
        //目前没有散装卖，注释
//        if(DrugTypeEnum.ZCY.getCode().equals(drug.getDrugType()) ||
//                DrugTypeEnum.XY.getCode().equals(drug.getDrugType()) || DrugTypeEnum.OTHER.getCode().equals(drug.getDrugType()) ||
//                DrugTypeEnum.HC.getCode().equals(drug.getDrugType())){//药材为3中成药，4西药，5耗材 存在零售,以剂量单位计算
//            if(CharUtil.isEmpty(drug.getTotalDose())){
//                throw new ServiceException("药品规格信息错误");
//            }
//            totalDose=drug.getTotalDose();
//        }
        //当前使用数量,剂量单位
        minMoth = moth * totalDose + minMoth + deliveryNum * totalDose + minDeliveryNum;
        int tempMoth = (int) Math.floor(Double.valueOf(minMoth) / Double.valueOf(totalDose));
        int tempMinMoth = minMoth - tempMoth * totalDose;
        Drug tempDrug = new Drug();
        tempDrug.setMothUse(tempMoth);
        tempDrug.setMinMothUse(tempMinMoth);
        tempDrug.setId(drug.getId());
        this.updateById(tempDrug);
    }

    @Override
    public List<Drug> finListByAdd(AdditionalQueryCriteria additionalQueryCriteria) {
        return baseMapper.finListByAdd(additionalQueryCriteria);
    }

    @Override
    public List<Drug> findDrugByInfoType(DrugInfoQueryCriteria drugInfoQueryCriteria) {
        return baseMapper.findDrugByInfoType(drugInfoQueryCriteria);
    }

    @Override
    public void outDrugs(DrugQueryCriteria criteria, HttpServletResponse response) throws IOException {
        List<Drug> drugs = baseMapper.findAllByPageable(criteria);
        List<Map<String, Object>> list = new ArrayList<>();
        for (Drug drug : drugs) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("药品ID", drug.getId());
            map.put("药品名称", drug.getDrugName());
            map.put("药品分类", DrugTypeEnum.findByCode(drug.getDrugType()));
            map.put("规格", drug.getDrugSpec());
            map.put("单位", drug.getDoseUnit());
            map.put("生产厂家", drug.getDrugManufactor());
            map.put("售价", drug.getSalePrice());
            map.put("库存", drug.getStock());
            map.put("有效标志", drug.getStatus() == 0 ? "正常" : "失效");
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    private Drug saveByFlag3(List<Object> rowlist) {
        Drug temp = new Drug();
        String drugCode = CharUtil.isEmpty(rowlist.get(0)) ? "" : rowlist.get(0).toString();
        String drugName = CharUtil.isEmpty(rowlist.get(1)) ? "" : rowlist.get(1).toString();
        String drugSpec = CharUtil.isEmpty(rowlist.get(2)) ? "" : rowlist.get(2).toString();
        String drugManufactor = CharUtil.isEmpty(rowlist.get(3)) ? "" : rowlist.get(3).toString();
        Integer drugType = DrugTypeEnum.findByValue(CharUtil.isEmpty(rowlist.get(4)) ? "" : rowlist.get(4).toString());
        String minDose = CharUtil.isEmpty(rowlist.get(5)) ? "" : rowlist.get(5).toString();
        String doseUnit = CharUtil.isEmpty(rowlist.get(6)) ? "" : rowlist.get(6).toString();
        String totalDose = CharUtil.isEmpty(rowlist.get(7)) ? "" : rowlist.get(7).toString();
        String totalDoseUnit = CharUtil.isEmpty(rowlist.get(8)) ? "" : rowlist.get(8).toString();
        String packageUnit = CharUtil.isEmpty(rowlist.get(9)) ? "" : rowlist.get(9).toString();
        String salePrice = CharUtil.isEmpty(rowlist.get(10)) ? "" : rowlist.get(10).toString();
        String isSellPiece = CharUtil.isEmpty(rowlist.get(11)) ? "" : rowlist.get(11).toString();
        String sellpiecePrice = CharUtil.isEmpty(rowlist.get(12)) ? "" : rowlist.get(12).toString();
        String approvalNumber = CharUtil.isEmpty(rowlist.get(13)) ? "" : rowlist.get(13).toString();
        if (CharUtil.isEmpty(drugName) || CharUtil.isEmpty(drugSpec) || CharUtil.isEmpty(drugManufactor) ||
                CharUtil.isEmpty(drugType) || CharUtil.isEmpty(minDose) || CharUtil.isEmpty(doseUnit) || CharUtil.isEmpty(totalDose) ||
                CharUtil.isEmpty(totalDoseUnit) || CharUtil.isEmpty(packageUnit) || CharUtil.isEmpty(salePrice)) {
            throw new ServiceException("信息不全导入失败");
        }
        if (!CharUtil.isEmpty(isSellPiece) && "是".equals(isSellPiece)) {
            isSellPiece = "0";
            if (CharUtil.isEmpty(sellpiecePrice)) {
                throw new ServiceException("可拆零的药品,拆零单价不能为空");
            }
        } else {
            isSellPiece = "1";
            sellpiecePrice = null;
        }
        temp.setStatus(0);
        temp.setDrugCode(drugCode);//商品编码
        temp.setDrugName(drugName);//商品名称
        temp.setDrugSpec(drugSpec);//规格
        temp.setDrugManufactor(drugManufactor);//生产厂家
        temp.setDrugType(Integer.valueOf(drugType));//商品分类
        temp.setMinDose(BigDecimal.valueOf(Double.valueOf(minDose)));
        temp.setDoseUnit(doseUnit);
        temp.setTotalDose(Integer.valueOf(totalDose));
        temp.setTotalDoseUnit(totalDoseUnit);
        temp.setPackageUnit(packageUnit);
        temp.setSalePrice(BigDecimal.valueOf(Double.valueOf(salePrice)));
        temp.setIsSellPiece(Integer.valueOf(isSellPiece));
        if ("0".equals(isSellPiece)) {
            temp.setSellPiecePrice(BigDecimal.valueOf(Double.valueOf(sellpiecePrice)));
        }
        temp.setApprovalNumber(approvalNumber);
        temp.setPharmacyId(LoginUserUtil.getPharmId());
        temp.setPinyin(PingYinUtil.getFirstSpell(drugName));
        return temp;
    }

    private Drug saveByFlag2(List<Object> rowlist) {
        Drug temp = new Drug();
        String drugName = CharUtil.isEmpty(rowlist.get(0)) ? "" : rowlist.get(0).toString();
        String drugSpec = CharUtil.isEmpty(rowlist.get(1)) ? "" : rowlist.get(1).toString();
        String drugManufactor = CharUtil.isEmpty(rowlist.get(2)) ? "" : rowlist.get(2).toString();
        Integer drugType = DrugTypeEnum.findByValue(CharUtil.isEmpty(rowlist.get(3)) ? "" : rowlist.get(3).toString());
        String doseUnit = CharUtil.isEmpty(rowlist.get(4)) ? "" : rowlist.get(4).toString();
        String packageUnit = CharUtil.isEmpty(rowlist.get(5)) ? "" : rowlist.get(5).toString();
        String salePrice = CharUtil.isEmpty(rowlist.get(6)) ? "" : rowlist.get(6).toString();
        String stockWarning = CharUtil.isEmpty(rowlist.get(7)) ? "" : rowlist.get(7).toString();
        String equivalent = CharUtil.isEmpty(rowlist.get(8)) ? "" : rowlist.get(8).toString();
        String coefficient = CharUtil.isEmpty(rowlist.get(9)) ? "" : rowlist.get(9).toString();
        String coefficientName = CharUtil.isEmpty(rowlist.get(10)) ? "" : rowlist.get(10).toString();

        if (CharUtil.isEmpty(drugName) || CharUtil.isEmpty(drugSpec) || CharUtil.isEmpty(drugManufactor) ||
                CharUtil.isEmpty(drugType) || CharUtil.isEmpty(doseUnit) ||
                CharUtil.isEmpty(packageUnit) || CharUtil.isEmpty(salePrice)) {
            throw new ServiceException("信息不全导入失败");
        }
        if (drugType.equals(DrugTypeEnum.PFKL.getCode()) && (CharUtil.isEmpty(equivalent) || CharUtil.isEmpty(coefficient) || CharUtil.isEmpty(coefficientName))) {
            throw new ServiceException("配方颗粒,克当量,系数,系数名不能为空");
        }
        temp.setStatus(0);
        temp.setDrugName(drugName);//商品名称
        temp.setDrugSpec(drugSpec);//规格
        temp.setDrugManufactor(drugManufactor);//生产厂家
        temp.setDrugType(Integer.valueOf(drugType));//商品分类
        temp.setDoseUnit(doseUnit);
        temp.setPackageUnit(packageUnit);
        temp.setSalePrice(BigDecimal.valueOf(Double.valueOf(salePrice)));
        if (drugType.equals(DrugTypeEnum.PFKL.getCode())) {
            temp.setDrugEquivalent(Double.valueOf(equivalent));
            temp.setCoefficient(Double.valueOf(coefficient));
            temp.setCoefficientName(coefficientName);
        }
        temp.setStockWarning(Integer.valueOf(stockWarning));
        temp.setPharmacyId(LoginUserUtil.getPharmId());
        temp.setPinyin(PingYinUtil.getFirstSpell(drugName));
        return temp;
    }

    private Drug saveByFlag1(List<Object> rowlist) {
        Drug temp = new Drug();
        String drugCode = CharUtil.isEmpty(rowlist.get(0)) ? "" : rowlist.get(0).toString();
        String drugName = CharUtil.isEmpty(rowlist.get(1)) ? "" : rowlist.get(1).toString();
        String drugSpec = CharUtil.isEmpty(rowlist.get(2)) ? "" : rowlist.get(2).toString();
        String drugManufactor = CharUtil.isEmpty(rowlist.get(3)) ? "" : rowlist.get(3).toString();
        Integer drugType = DrugTypeEnum.findByValue(CharUtil.isEmpty(rowlist.get(4)) ? "" : rowlist.get(4).toString());
        String minDose = CharUtil.isEmpty(rowlist.get(5)) ? "" : rowlist.get(5).toString();
        String doseUnit = CharUtil.isEmpty(rowlist.get(6)) ? "" : rowlist.get(6).toString();
        String totalDose = CharUtil.isEmpty(rowlist.get(7)) ? "" : rowlist.get(7).toString();
        String totalDoseUnit = CharUtil.isEmpty(rowlist.get(8)) ? "" : rowlist.get(8).toString();
        String packageUnit = CharUtil.isEmpty(rowlist.get(9)) ? "" : rowlist.get(9).toString();
        String salePrice = CharUtil.isEmpty(rowlist.get(10)) ? "" : rowlist.get(10).toString();
        String isSellPiece = CharUtil.isEmpty(rowlist.get(11)) ? "" : rowlist.get(11).toString();
        String sellpiecePrice = CharUtil.isEmpty(rowlist.get(12)) ? "" : rowlist.get(12).toString();
        String stockWarning = CharUtil.isEmpty(rowlist.get(13)) ? "" : rowlist.get(13).toString();
        String approvalNumber = CharUtil.isEmpty(rowlist.get(14)) ? "" : rowlist.get(14).toString();
        if (CharUtil.isEmpty(drugName) || CharUtil.isEmpty(drugSpec) || CharUtil.isEmpty(drugManufactor) ||
                CharUtil.isEmpty(drugType) || CharUtil.isEmpty(minDose) || CharUtil.isEmpty(doseUnit) || CharUtil.isEmpty(totalDose) ||
                CharUtil.isEmpty(totalDoseUnit) || CharUtil.isEmpty(packageUnit) || CharUtil.isEmpty(salePrice)) {
            throw new ServiceException("信息不全导入失败");
        }
        if (!CharUtil.isEmpty(isSellPiece) && "是".equals(isSellPiece)) {
            isSellPiece = "0";
            if (CharUtil.isEmpty(sellpiecePrice)) {
                throw new ServiceException("可拆零的药品,拆零单价不能为空");
            }
        } else {
            isSellPiece = "1";
            sellpiecePrice = null;
        }
        temp.setStatus(0);
        temp.setDrugCode(drugCode);//商品编码
        temp.setDrugName(drugName);//商品名称
        temp.setDrugSpec(drugSpec);//规格
        temp.setDrugManufactor(drugManufactor);//生产厂家
        temp.setDrugType(Integer.valueOf(drugType));//商品分类
        temp.setMinDose(BigDecimal.valueOf(Double.valueOf(minDose)));
        temp.setDoseUnit(doseUnit);
        temp.setTotalDose(Integer.valueOf(totalDose));
        temp.setTotalDoseUnit(totalDoseUnit);
        temp.setPackageUnit(packageUnit);
        temp.setSalePrice(BigDecimal.valueOf(Double.valueOf(salePrice)));
        temp.setIsSellPiece(Integer.valueOf(isSellPiece));
        if ("0".equals(isSellPiece)) {
            temp.setSellPiecePrice(BigDecimal.valueOf(Double.valueOf(sellpiecePrice)));
        }
        temp.setStockWarning(Integer.valueOf(stockWarning));
        temp.setApprovalNumber(approvalNumber);
        temp.setPharmacyId(LoginUserUtil.getPharmId());
        temp.setPinyin(PingYinUtil.getFirstSpell(drugName));
        return temp;
    }
}
